
package com.oahcfly.chgame.core.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.oahcfly.chgame.core.Chao;
import com.oahcfly.chgame.core.listener.CHProgressBarListener;

/**
 * 
 * 圆形冷却进度条
 * 参考自：http://blog.csdn.net/wuhaishengxxx/article/details/46642791
 *  
 * 
 * @author haocao
 *
 */
public class CHCirclePngProgressBar extends Actor {
	// 顶点属性个数：(x,y,color,u,v)
	static final int VERTEX_SIZE = 2 + 1 + 2;
	static final int MAX_VERTICES = 26;
	// 总属性个数
	static final int SPRITE_SIZE = MAX_VERTICES * VERTEX_SIZE;

	// 属性数组元素个数 ： 坐标(x,y) 颜色(r,g,b,a) 纹理(u,v)
	public final int POS_COMPONENTS = 2;
	public final int COLOR_COMPONENTS = 4;
	public final int TEXCOORD_COMPONENTS = 2;

	private Texture topTexture, bgTexture;
	private Mesh mesh;
	private ShaderProgram shader;
	private float[] spriteVertices;
	// 冷却时长
	private float duration;

	public CHCirclePngProgressBar (String bgPngPath, String topPngPath, float duration) {
		this.duration = duration;
		topTexture = Chao.game.getTexture(topPngPath);
		bgTexture = Chao.game.getTexture(bgPngPath);

		setSize(topTexture.getWidth(), topTexture.getHeight());
		setOrigin(Align.center);
		/** 
		 *  使用默认的shader 
		 *  一般不指定ShaderProgram，我们使用SpriteBatch的时候都是使用默认的shader 
		 */
		this.shader = SpriteBatch.createDefaultShader();

		// 设置顶点数据类型为数组类型  
		Mesh.VertexDataType vertexDataType = Mesh.VertexDataType.VertexArray;

		/** 
		 * 只需要处理 ：顶点坐标、颜色、纹理坐标  
		 */
		VertexAttribute[] vertexAttributes = new VertexAttribute[3];
		vertexAttributes[0] = new VertexAttribute(Usage.Position, POS_COMPONENTS, "a_position");
		vertexAttributes[1] = new VertexAttribute(Usage.ColorPacked, COLOR_COMPONENTS, "a_color");
		vertexAttributes[2] = new VertexAttribute(Usage.TextureCoordinates, TEXCOORD_COMPONENTS, "a_texCoord0");

		this.mesh = new Mesh(vertexDataType, false, MAX_VERTICES, MAX_VERTICES, vertexAttributes);

		// 
		Array<Vector2> pointsArray = generatePoints();
		/** 
		 * 初始化顶点数据 
		 */
		spriteVertices = new float[SPRITE_SIZE];
		for (int i = 0; i < MAX_VERTICES; i++) {
			Vector2 vector2 = pointsArray.get(i);
			float tx = vector2.x;
			float ty = vector2.y;
			spriteVertices[i * 5 + 0] = tx;// 坐标x
			spriteVertices[i * 5 + 1] = ty;// 坐标y
			Vector2 uVector2 = getUV(tx, ty);
			spriteVertices[i * 5 + 3] = uVector2.x;
			spriteVertices[i * 5 + 4] = uVector2.y;
		}
	}

	private int progressIdx = 0;

	public void startProgress () {
		progressIdx = 0;
		// 单步时长
		float singleDuration = duration / (MAX_VERTICES - 1);
		addAction(Actions.repeat(MAX_VERTICES - 1, Actions.delay(singleDuration, Actions.run(new Runnable() {

			@Override
			public void run () {
				// 
				progressIdx++;

				onProgress();
			}
		}))));
	}

	private void onProgress () {
		if (progressIdx == 0 && progressBarListener != null) {
			progressBarListener.onStart();
		}

		boolean isEnd = progressIdx == MAX_VERTICES - 1;
		if (isEnd && progressBarListener != null) {
			progressBarListener.onFinish();
		}

		if (isEnd) {
			stoped = false;
			clearActions();
		}

	}

	private boolean stoped = false;

	/**
	 * 终止进度
	 */
	public void stopProgress () {
		stoped = true;
	}

	/**
	 * 重置进度
	 */
	public void resetProgress () {
		stoped = false;
		clearActions();
		progressIdx = 0;
	}

	/**
	 * 恢复进度
	 */
	public void resumeProgress () {
		stoped = false;
	}

	/**
	 * 是否处于进度中
	 * @return
	 */
	public boolean isProgressing () {
		return progressIdx >= 1;
	}

	@Override
	public void act (float delta) {
		if (stoped) return;
		super.act(delta);
	}

	@Override
	public void draw (Batch batch, float parentAlpha) {
		Color color = getColor();
		batch.setColor(color.r, color.g, color.b, color.a);

		//调用ShapeRender绘制几何图形时无法实现半透明颜色的问题
		Gdx.gl.glEnable(GL20.GL_BLEND);
		Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
		// 开启图形附上纹理
		Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);

		float[] tmpSpriteVertices = new float[5 * (progressIdx + 1)];
		float x = getX(Align.center) - bgTexture.getWidth() / 2;
		float y = getY(Align.center) - bgTexture.getHeight() / 2;
		float fColor = getColor().toFloatBits();
		for (int i = 0; i < MAX_VERTICES; i++) {
			if (i < progressIdx + 1) {
				tmpSpriteVertices[i * 5 + 0] = spriteVertices[i * 5 + 0] + x;// 坐标x
				tmpSpriteVertices[i * 5 + 1] = spriteVertices[i * 5 + 1] + y;// 坐标y
				tmpSpriteVertices[i * 5 + 2] = fColor;// 颜色
				Vector2 uVector2 = getUV(spriteVertices[i * 5 + 0], spriteVertices[i * 5 + 1]);
				tmpSpriteVertices[i * 5 + 3] = uVector2.x;// 纹理坐标u
				tmpSpriteVertices[i * 5 + 4] = uVector2.y;// 纹理坐标v
			}
		}

		this.bgTexture.bind();
		this.mesh.setVertices(tmpSpriteVertices, 0, tmpSpriteVertices.length);
		this.mesh.render(this.shader, GL20.GL_TRIANGLE_FAN, 0, tmpSpriteVertices.length / 5);

		// 顶部蒙版纹理
		batch.draw(topTexture, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(),
			getRotation(), 0, 0, (int)getWidth(), (int)getHeight(), false, false);

	}

	private CHProgressBarListener progressBarListener;

	public void setProgressBarListener (CHProgressBarListener progressBarListener) {
		this.progressBarListener = progressBarListener;
	}

	/**
	 * 计算纹理坐标 uv以左上角为基准
	 * 
	 * @param x 以左下角为基准，范围[0,w]
	 * @param y 以左下角为基准，范围[0,h]
	 * @return
	 */
	private Vector2 getUV (float x, float y) {
		Vector2 vector2 = new Vector2(x / bgTexture.getWidth(), 1 - y / bgTexture.getHeight());
		return vector2;
	}

	private Array<Vector2> generatePoints () {
		// 原点：左下角
		float w = bgTexture.getWidth();
		float h = bgTexture.getHeight();
		Array<Vector2> array = new Array<Vector2>();
		// 圆心
		array.add(new Vector2(2 * w / 4, 2 * h / 4));

		int MAX_POINTS = 6;
		// 右上4
		for (int i = MAX_POINTS / 2; i <= MAX_POINTS; i++) {
			array.add(new Vector2(i * w / MAX_POINTS, h));
		}
		// 右侧6
		for (int i = MAX_POINTS - 1; i >= 0; i--) {
			array.add(new Vector2(w, i * h / MAX_POINTS));
		}

		// 底6
		for (int i = MAX_POINTS - 1; i >= 0; i--) {
			array.add(new Vector2(w * i / MAX_POINTS, 0));
		}

		// 左6
		for (int i = 1; i <= MAX_POINTS; i++) {
			array.add(new Vector2(0, i * h / MAX_POINTS));
		}

		// 左上3
		for (int i = 1; i <= MAX_POINTS / 2; i++) {
			array.add(new Vector2(w * i / MAX_POINTS, h));
		}
		return array;
	}
}
